<template>
  <canvas id="scoreProgressCanvas" :width="boxWidth" :height="boxWidth"></canvas>
</template>

<script>
import { utilJs } from '@/utils/common';

export default {
  components: {},

  props: {
    progress: {
      //当前进度0-100
      type: Number,
      default: 0
    },
    width: {
      //当前canvas宽高，单位rem
      type: Number,
      default: 8
    },
    color: {
      //当前绘制主题色
      type: String,
      default: ''
    }
  },

  data() {
    return {
      boxWidth: 200
    };
  },

  computed: {
    themeColor() {
      //没传默认为主题色,将颜色转成rgb色值
      if (!this.color) {
        const rgbColor = utilJs.hexToRgb(this.$getThemeColor());
        return rgbColor;
      }
      if (this.color.toString().includes('#')) {
        const rgbColor = utilJs.hexToRgb(this.color);
        return rgbColor;
      }
      if (this.color.toString().includes('rgba')) {
        return this.color;
      }
      const rgbColor = utilJs.hexToRgb(this.$getThemeColor());
      return rgbColor;
    }
  },
  watch: {
    progress() {
      this.startDrawAni();
    }
  },

  mounted() {
    this._baseFontSize = this.getFontBaseSize();
    this.boxWidth = this.width * this._baseFontSize;
    this._trackWidth = 0.4 * this._baseFontSize; //进度条背景宽度 0.3rem
    this._progressWidth = 0.7 * this._baseFontSize; //进度条进度宽度 0.7rem
    this._progressBarWidth = 0.5 * this._baseFontSize; // 进度条尾部圆环宽度
    this._centerX = this.boxWidth / 2; //中心点坐标
    this._ctx = null;
    this.initCanvas();
    this.startDrawAni();
  },

  methods: {
    /**
     * 获取rem转px转化大小，也就是html的fontsize的大小
     * @returns {number} 转化数值
     */
    getFontBaseSize() {
      let cWidth = document.documentElement.clientWidth;
      cWidth = cWidth > 640 ? 640 : cWidth;
      return 20 * (cWidth / 320);
    },
    /**
     * 初始化画布
     */
    initCanvas() {
      const canvas = document.getElementById('scoreProgressCanvas');
      this._ctx = canvas.getContext('2d');
    },
    /**
     * 开始绘制动画
     */
    startDrawAni() {
      this.$nextTick(() => {
        this._startPorgress = 0;
        requestAnimationFrame(this.drawCanvas);
      });
    },
    drawCanvas() {
      if (!this._ctx) {
        return;
      }
      if (this.progress == 0) {
        return;
      }
      //最大绘制绘制进度限制
      if (this.progress > 100) {
        this.progress = 100;
      }
      //每隔16ms进度+2 ，也就是说动画执行时间最多是16*100/2 = 800ms
      this._startPorgress += 2;
      //绘制最大进度
      if (this._startPorgress > this.progress) {
        this._startPorgress = this.progress;
      }
      const progressRadius = (this.boxWidth - this._progressWidth) / 2;
      //清除画布
      this._ctx.clearRect(0, 0, this.boxWidth, this.boxWidth);

      //***绘制背景进度条START***
      this._ctx.save();
      this._ctx.beginPath();
      //圆心为中心点，半径=（宽度-进度条宽度）/2
      this._ctx.arc(this._centerX, this._centerX, progressRadius, Math.PI, Math.PI * 2);
      this._ctx.lineWidth = this._trackWidth;
      this._ctx.strokeStyle = `rgba(${this.themeColor}, 0.1)`;
      this._ctx.lineCap = 'round';
      this._ctx.stroke();
      this._ctx.restore();
      //***绘制背景进度条END***
      //***绘制内环进度条START***
      this._ctx.save();
      this._ctx.beginPath();
      //内环半径 = 宽度/2 - 进度条宽度 - 进度条宽度/2 + 内环半径/2
      this._ctx.arc(this._centerX, this._centerX, progressRadius - this._progressWidth + this._trackWidth / 2, Math.PI, Math.PI * 2);
      this._ctx.lineWidth = this._progressWidth;
      //内环渐变从圆心到外环
      const gradient = this._ctx.createRadialGradient(this._centerX, this._centerX, 0, this._centerX, this._centerX, progressRadius + this._trackWidth / 2);
      gradient.addColorStop(0, `rgba(${this.themeColor}, 1)`);
      gradient.addColorStop(0.9, `rgba(${this.themeColor}, 0.01)`);
      gradient.addColorStop(1, `rgba(${this.themeColor}, 0)`);
      this._ctx.strokeStyle = gradient;
      this._ctx.lineCap = 'round';
      this._ctx.stroke();
      this._ctx.restore();
      //***绘制内环进度条END***
      //***绘制进度条START***
      this._ctx.save();
      this._ctx.beginPath();
      this._ctx.arc(this._centerX, this._centerX, progressRadius, Math.PI, Math.PI * (1 + this._startPorgress / 100));
      this._ctx.lineWidth = this._progressWidth;
      this._ctx.strokeStyle = `rgba(${this.themeColor}, 1)`;
      this._ctx.lineCap = 'round';
      this._ctx.stroke();
      this._ctx.restore();
      //***绘制进度条END***
      //***绘制进度条尾部圆环START***
      const startAngle = Math.PI;
      const endAngle = Math.PI * 2;
      const angle = startAngle + (this._startPorgress / 100) * (endAngle - startAngle);
      const x = this._centerX + progressRadius * Math.cos(angle);
      const y = this._centerX + progressRadius * Math.sin(angle);
      const gradientBar = this._ctx.createRadialGradient(x, y, 0, x, y, this._progressBarWidth);
      gradientBar.addColorStop(0, `rgba(${this.themeColor}, 0.1`);
      gradientBar.addColorStop(0.5, `rgba(${this.themeColor}, 0.1)`);
      gradientBar.addColorStop(1, `rgba(${this.themeColor}, 0)`);
      this._ctx.save();
      this._ctx.beginPath();
      this._ctx.arc(x, y, this._progressBarWidth / 2, 0, Math.PI * 2);
      this._ctx.fillStyle = '#ffffff';
      this._ctx.fill();
      this._ctx.restore();
      this._ctx.beginPath();
      this._ctx.arc(x, y, (this._progressBarWidth - this._progressBarWidth / 4) / 2, 0, 2 * Math.PI);
      this._ctx.fillStyle = `rgba(${this.themeColor}, 0.8)`;
      this._ctx.fill();
      //***绘制进度条尾部圆环END***
      //如果当前进度条超过了绘制进度，则动画结束不在绘制
      if (this._startPorgress >= this.progress) {
        return;
      }
      requestAnimationFrame(this.drawCanvas);
    }
  }
};
</script>

<style scoped></style>
